package com.eshipenet.shipnet.shiprpc.util;

import com.google.protobuf.*;
import net.sf.json.JSONObject;
import org.json4s.JsonAST;
import org.json4s.JsonInput;
import org.json4s.jackson.JsonMethods$;
import scala.Tuple2;
import scala.collection.immutable.List;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class GetJObjectUtil {

  /**
   * struct转JObject
   *
   * @param struct
   * @return
   */

  public static JsonAST.JObject getWhere(Struct struct) {


    Map<String, Value> m = struct.getFieldsMap();

    Iterator<Map.Entry<String, Value>> iterator = m.entrySet().iterator();

    ArrayList<Tuple2<String, JsonAST.JValue>> arrayList = whileList(iterator);

    List<Tuple2<String, JsonAST.JValue>> lists =
      scala.collection.JavaConverters.asScalaIterator(arrayList.iterator()).toList();

    JsonAST.JObject jObject = new JsonAST.JObject(lists);


    return jObject;

  }


  /**
   * 遍历数据，返回列表数据
   *
   * @param iterator
   * @return
   */
  public static ArrayList<Tuple2<String, JsonAST.JValue>> whileList(Iterator<Map.Entry<String, Value>> iterator) {

    ArrayList<Tuple2<String, JsonAST.JValue>> arrayList = new ArrayList<Tuple2<String, JsonAST.JValue>>();

    while (iterator.hasNext()) {
      Map.Entry<String, Value> index = iterator.next();
      String key = index.getKey();
      Value value = index.getValue();

      //根据数据类型返回数据
      Tuple2<String, JsonAST.JValue> tuple = new Tuple2<>(key, getValue(value));

      arrayList.add(tuple);


    }

    return arrayList;


  }


  public static JsonAST.JValue getValue(Value value) {


    Value.KindCase kindCase = value.getKindCase();

    //判断数据类型
    switch (kindCase) {

      case BOOL_VALUE:
        boolean boolean_value = value.getBoolValue();
        JsonAST.JBool jBool = new JsonAST.JBool(boolean_value);
        return jBool;

      case NUMBER_VALUE:
        double double_value = value.getNumberValue();
        JsonAST.JDouble jDouble = new JsonAST.JDouble(double_value);
        return jDouble;

      case NULL_VALUE:
        //                NullValue null_value=value.getNullValue();
        JsonAST.JNull$ jNull = JsonAST.JNull$.MODULE$;
        return jNull;

      case STRING_VALUE:
        String string_value = value.getStringValue();
        JsonAST.JString jString = new JsonAST.JString(string_value);
        return jString;

      case LIST_VALUE:
        ListValue list_value = value.getListValue();

        ArrayList<JsonAST.JValue> arrayList = new ArrayList<JsonAST.JValue>();
        for (int i = 0; i < list_value.getValuesCount(); i++) {

          Value v = list_value.getValues(i);
          JsonAST.JValue jValue = getValue(v);
          arrayList.add(jValue);
        }

        List<JsonAST.JValue> list = scala.collection.JavaConverters.asScalaIterator(arrayList.iterator()).toList();
        JsonAST.JArray jArray = new JsonAST.JArray(list);

        return jArray;


      case STRUCT_VALUE:
        Struct struct_value = value.getStructValue();
        JsonAST.JObject jObject = getWhere(struct_value);
        return jObject;

      case KIND_NOT_SET:

        break;

    }

    JsonAST.JString jString1 = new JsonAST.JString("none");
    return jString1;

  }


  /**
   * struct转string
   *
   * @param struct
   * @return
   */
  public static String getData(Struct struct) {


    Map<String, Value> m = struct.getFieldsMap();

    Iterator<Map.Entry<String, Value>> iterator = m.entrySet().iterator();

    JSONObject object = new JSONObject();
    while (iterator.hasNext()) {
      Map.Entry<String, Value> index = iterator.next();
      String key = index.getKey();
      Value value = index.getValue();

      Object o = getObject(value);
      object.put(key, o);

    }

    //将JSON对象转化为字符串
    String objStr = object.toString();

    return objStr;

  }


  public static Object getObject(Value value) {


    Value.KindCase kindCase = value.getKindCase();

    //判断数据类型
    switch (kindCase) {

      case BOOL_VALUE:
        boolean boolean_value = value.getBoolValue();
        return boolean_value;

      case NUMBER_VALUE:
        double double_value = value.getNumberValue();
        return double_value;

      case NULL_VALUE:

        return null;

      case STRING_VALUE:
        String string_value = value.getStringValue();
        return string_value;

      case STRUCT_VALUE:
        Struct struct_value = value.getStructValue();
        return struct_value;

      case KIND_NOT_SET:

        break;

    }


    return null;

  }


  /**
   * string转Struct
   *
   * @param data
   * @return
   */
  public static Struct getData(String data) {

    Struct struct = Struct.newBuilder().build();

    if (data != null && data != "") {
      try {

        JsonInput jsonInput = new org.json4s.StringInput(data);

        JsonAST.JValue jValue = JsonMethods$.MODULE$.parse(jsonInput, true, true);

        if (jValue instanceof JsonAST.JObject) {
          JsonAST.JObject jObject = (JsonAST.JObject) jValue;
          struct = toStruct(jObject);
        }

        return struct;

      } catch (Exception e) {

        e.printStackTrace();
      }

    }

    return struct;


  }


  public static Struct toStruct(JsonAST.JObject jObject) {

    List<Tuple2<String, JsonAST.JValue>> lists = jObject.obj();

    scala.collection.Iterator<Tuple2<String, JsonAST.JValue>> iterator = lists.iterator();

    Map<String, Value> m = new HashMap<>();
    while (iterator.hasNext()) {

      Tuple2<String, JsonAST.JValue> tuple = iterator.next();
      String key = tuple._1;
      JsonAST.JValue jValue = tuple._2;

      m.put(key, toValue(jValue));


    }

    Struct struct = Struct.newBuilder().putAllFields(m).build();

    return struct;
  }

  public static Value toValue(JsonAST.JValue jValue) {

    Value value;

    if (jValue instanceof JsonAST.JObject) {

      JsonAST.JObject obj = (JsonAST.JObject) jValue;
      Struct s = toStruct(obj);

      value = Value.newBuilder().mergeStructValue(s).build();
      return value;

    } else if (jValue instanceof JsonAST.JString) {
      JsonAST.JString obj = (JsonAST.JString) jValue;

      StringValue stringValue = StringValue.newBuilder().setValue(obj.values()).build();

      value = Value.newBuilder().setStringValue(stringValue.getValue()).build();

      return value;
    } else if (jValue instanceof JsonAST.JNull$) {

      NullValue nullValue = NullValue.NULL_VALUE;

      value = Value.newBuilder().setNullValue(nullValue).build();

      return value;
    } else if (jValue instanceof JsonAST.JNumber) {

      JsonAST.JInt jInt = (JsonAST.JInt) jValue;

      Int32Value int32Value = Int32Value.newBuilder().setValue(jInt.num().intValue()).build();

      value = Value.newBuilder().setNumberValue(int32Value.getValue()).build();

      return value;

    }else if(jValue instanceof JsonAST.JDouble){

      JsonAST.JDouble jDouble = (JsonAST.JDouble) jValue;

      DoubleValue doubleValue = DoubleValue.newBuilder().setValue(jDouble.values()).build();

      value = Value.newBuilder().setNumberValue(doubleValue.getValue()).build();

      return value;

    }else if (jValue instanceof JsonAST.JBool) {

      JsonAST.JBool jBool = (JsonAST.JBool) jValue;

      BoolValue boolValue = BoolValue.newBuilder().setValue(jBool.value()).build();

      value = Value.newBuilder().setBoolValue(boolValue.getValue()).build();
      return value;
    } else {

      NullValue nullValue = NullValue.NULL_VALUE;

      value = Value.newBuilder().setNullValue(nullValue).build();

      return value;
    }


  }




  public static void main(String[] args) {
    String data = "{\"name\":\"1\",\"id\":false}";

    Struct struct = getData(data);

    System.out.println(struct);
  }
}
